home *** CD-ROM | disk | FTP | other *** search
/ Floppyshop 2 / Floppyshop - 2.zip / Floppyshop - 2.iso / art&graf.ix / art-0039 / source / manywind.mod < prev    next >
Text File  |  1997-04-16  |  15KB  |  571 lines

  1. IMPLEMENTATION MODULE ManyWindows;
  2.  
  3. (*-----------------------------------------------------------------------*)
  4. (* See notes in defintion module.                                        *)
  5. (*                                                                       *)
  6. (*                                                                       *)
  7. (*  7/ 9/89 LGM : Original.                                              *)
  8. (*-----------------------------------------------------------------------*)
  9. (* IMPORT Trace; *)
  10. FROM     SYSTEM         IMPORT     ADR, ADDRESS;
  11. FROM     Application    IMPORT     appl_init, appl_exit;
  12. FROM     Forms         IMPORT     form_alert;
  13. IMPORT     Window;
  14. FROM       Window        IMPORT     Components, ComponentSet, wind_update;
  15. IMPORT     Graphics;
  16. IMPORT    Forms;
  17. IMPORT     VDI;
  18. FROM     Strings     IMPORT     (* type *) String,
  19.                            (* func *) Concat, Assign,
  20.                                          Delete, Pos, Length, Copy ;
  21. FROM     Bios         IMPORT getRez;
  22. FROM     Storage        IMPORT ALLOCATE, DEALLOCATE, Cleanup, MaxBlocks;
  23.  
  24. CONST
  25.     NULLCHAR     =     0C;
  26.     CMaxWindows    =     4;
  27.  
  28. TYPE
  29.       ActiveWindows     = ARRAY [ 0 .. CMaxWindows-1 ] OF WindowPtr;
  30.   
  31. VAR
  32.      TheWindows        : ActiveWindows;
  33.     WindowCount        : CARDINAL;
  34.      DesktopWindow        : WindowPtr;    
  35.  
  36.     ScreenUpdateCount    : INTEGER=0; (* screen being updated *)
  37.  
  38.         dumi            : INTEGER;
  39.     dumc            : CARDINAL;
  40.  
  41.  
  42. PROCEDURE NullFill ( VAR str : ARRAY OF CHAR );
  43.   VAR i : CARDINAL;
  44.   BEGIN
  45.     FOR i := 0 TO SHORT(HIGH(str)) DO str[i] := NULLCHAR END; 
  46.   END NullFill;
  47.  
  48.  
  49. (* a useful utility *)
  50. PROCEDURE ShowAlert(  s      : ARRAY OF CHAR; (* Alert string to show *)
  51.                       n, def : CARDINAL ) : CARDINAL;
  52.                           (* ok button = 1 *)
  53. CONST
  54.   IconStr       = '[3][';
  55.   OneButtonStr  = '][  OK  ]';
  56.   TwoButtonStr  = '][  OK  |CANCEL]';
  57.  
  58. VAR
  59.   str         : String ;
  60.   result     : INTEGER ;
  61.   DefaultButton,
  62.   i         : CARDINAL ;
  63.  
  64.   BEGIN
  65.     DefaultButton := def;
  66.     NullFill(str);
  67.     Concat(IconStr,s,str);
  68.     IF n = 1 THEN
  69.        Concat(str,OneButtonStr,str);
  70.     ELSE
  71.        Concat(str,TwoButtonStr,str);
  72.     END; (* if *)
  73.     RETURN Forms.form_alert(DefaultButton,str) ;
  74.   END ShowAlert ;
  75.  
  76.  
  77. PROCEDURE ToCornersRect( in : XYWHRect; VAR out : CornersRect );
  78.   BEGIN
  79.     WITH out DO
  80.       XL := in.X;
  81.       YL := in.Y;
  82.       XR := in.X + in.Width  - 1; 
  83.       YR := in.Y + in.Height - 1;
  84.     END;
  85.   END ToCornersRect;
  86.  
  87.  
  88. PROCEDURE ToXYWHRect( in :  CornersRect; VAR out : XYWHRect; );
  89.   BEGIN
  90.     IF in.XL > in.XR THEN
  91.       WITH out DO
  92.         X     := in.XR;
  93.         Y    := in.YR;
  94.         Width     := in.XL - in.XR + 1; 
  95.         Height    := in.YL - in.YR + 1;
  96.       END;
  97.     ELSE 
  98.       WITH out DO
  99.         X     := in.XL;
  100.         Y    := in.YL;
  101.         Width     := in.XR - in.XL + 1; 
  102.         Height    := in.YR - in.YL + 1;
  103.       END;
  104.     END;
  105.   END ToXYWHRect;
  106.  
  107.  
  108. PROCEDURE BeginScreenUpdate;
  109.   BEGIN
  110.     IF ScreenUpdateCount = 0 THEN
  111.     dumc := wind_update(1);
  112.     END;
  113.     INC(ScreenUpdateCount);       
  114.   END BeginScreenUpdate;
  115.  
  116.  
  117. PROCEDURE EndScreenUpdate;
  118.   BEGIN
  119.     IF ScreenUpdateCount = 1 THEN
  120.     dumc := wind_update(0);
  121.     END;
  122.     DEC(ScreenUpdateCount);       
  123.   END EndScreenUpdate;
  124.  
  125.  
  126. (* return window number, negative if not opened by me *)
  127. PROCEDURE GetWindowIndex( wp : WindowPtr ) : INTEGER;
  128.   VAR i : INTEGER;
  129.   BEGIN
  130.     i:=0;
  131.     WHILE ( i < CMaxWindows )
  132.      AND  ( TheWindows[i] <> wp ) DO
  133.        INC(i);
  134.     END;
  135.     IF ( wp = NIL         )
  136.     OR ( i >= CMaxWindows ) THEN
  137.        i := -1; END;
  138.     RETURN i;
  139.   END GetWindowIndex;
  140.  
  141.  
  142. PROCEDURE NewWindow() : WindowPtr;
  143.   VAR wp : WindowPtr;
  144.       i  : INTEGER;
  145.   BEGIN
  146.     i:=0;
  147.     WHILE ( i < CMaxWindows )
  148.      AND  ( TheWindows[i] <> NIL ) DO
  149.        INC(i);
  150.     END;
  151.  
  152.     wp := NIL;
  153.     IF WindowCount < CMaxWindows THEN
  154.        NEW( wp );
  155.        IF wp <> NIL THEN
  156.           TheWindows[i] := wp;
  157.           INC(WindowCount);
  158.  
  159.        ELSE
  160.           dumc := ShowAlert('Unable To Create Window',1,1);
  161.        END;
  162.  
  163.     ELSE
  164.        dumc := ShowAlert('To Many Open Windows',1,1);
  165.     END;
  166.     RETURN wp;
  167.   END NewWindow;
  168.  
  169.  
  170. PROCEDURE DestroyWindow( wp : WindowPtr );
  171.   VAR i : INTEGER;
  172.   BEGIN
  173.     i := GetWindowIndex(wp); 
  174.     IF i < 0 THEN 
  175.        dumc := ShowAlert('Cannot Dispose of wondow.|Window pointer not found',1,1);
  176.     ELSE
  177.        TheWindows[i] := NIL;
  178.        DISPOSE( wp );
  179.     END;
  180.   END DestroyWindow;
  181.  
  182.  
  183. PROCEDURE GetWindowHandle( wp : WindowPtr ) : INTEGER;
  184.   BEGIN
  185.     RETURN wp^.Handle;
  186.   END GetWindowHandle;
  187.  
  188.  
  189. PROCEDURE GetWindowPtr( handle : INTEGER ) : WindowPtr;
  190.   VAR i : CARDINAL;
  191.   BEGIN
  192.     FOR i:= 0 TO CMaxWindows-1 DO
  193.       IF TheWindows[i]^.Handle = handle THEN
  194.          RETURN TheWindows[i];
  195.       END;
  196.     END;
  197.     RETURN NIL;
  198.   END GetWindowPtr;
  199.  
  200.  
  201. PROCEDURE GetDesktopWindowInfo( wp : WindowPtr );
  202.   CONST 
  203.     DesktopWindow = 0;
  204.     WorkXYWH      = 4;
  205.   
  206.   BEGIN
  207.     (* get max window size on the desk top *)
  208.     IF  Window.wind_get( DesktopWindow,
  209.                          WorkXYWH, (* input *)
  210.                          wp^.Outer.X,
  211.                          wp^.Outer.Y,
  212.                          wp^.Outer.Width,
  213.                          wp^.Outer.Height ) = 0 THEN
  214.        dumc := ShowAlert('Cannot get destop size',1,1);
  215.       HALT
  216.      END;
  217.   END GetDesktopWindowInfo;
  218.  
  219.  
  220. PROCEDURE HideMouse;
  221.   BEGIN
  222.     VDI.v_hide_c( VDIHandle );
  223.   END HideMouse;
  224.  
  225.  
  226. PROCEDURE ShowMouse;
  227.   BEGIN  
  228.     VDI.v_show_c( VDIHandle, FALSE ); (* Force mouse to be shown *)
  229.   END ShowMouse;
  230.   
  231.  
  232. PROCEDURE StartApplication; 
  233.   VAR
  234.      i       : INTEGER;
  235.      workin  : ARRAY [0 .. 100] OF INTEGER;
  236.      workout : ARRAY [0 .. 100] OF INTEGER;
  237.      str     : String;
  238.   BEGIN
  239.     AESApplId := appl_init();
  240.  
  241.     (* get VDI handle used by AES *)
  242.     VDIHandle :=
  243.           Graphics.graf_handle(DesktopWindow^.Font.CharWidth,
  244.                                DesktopWindow^.Font.CharHeight,
  245.                    DesktopWindow^.Font.Width,
  246.                    DesktopWindow^.Font.Height);
  247.     GetDesktopWindowInfo( DesktopWindow );
  248.  
  249.     (* Open VDI Virtual workstation for this program *)
  250.     FOR i:=0 TO 9 DO workin[i]:=1; END;
  251.     workin[10]:=2; (* set raster co-ordinates *)
  252.     VDI.v_opnvwk( workin, VDIHandle, workout );
  253.     IF ( VDIHandle = 0 ) THEN
  254.        i := ShowAlert( "Unable to open | virtual workstation]",1,1);
  255.        HALT;
  256.     END; (* if *)
  257.     (* set fill for screen clear *) 
  258.     i := VDI.vsf_interior(VDIHandle, VDI.SolidFill);
  259.     i := VDI.vsf_color(VDIHandle, VDI.White);
  260.   END StartApplication;   
  261.  
  262.  
  263. PROCEDURE CalcWorkareaSize( wp : WindowPtr ); (* use AWindow *)
  264.   CONST
  265.     ReturnWorkareaSize = 1;
  266.  
  267.   BEGIN
  268.     (* Now get work area size of AWindow using border components *)
  269.    IF Window.wind_calc( ReturnWorkareaSize,
  270.                            wp^.Components,
  271.                            wp^.Outer.X,
  272.                            wp^.Outer.Y,
  273.                            wp^.Outer.Width,
  274.                            wp^.Outer.Height,
  275.  
  276.                            wp^.Workarea.X,
  277.                            wp^.Workarea.Y,
  278.                            wp^.Workarea.Width,
  279.                            wp^.Workarea.Height ) = 0 THEN END;
  280.   END CalcWorkareaSize;
  281.  
  282.  
  283.  
  284. PROCEDURE CreateAWindow( components : ComponentSet) : WindowPtr ;
  285.   CONST
  286.      WindowName = 2;
  287.   VAR
  288.     wp            : WindowPtr;
  289.     WindowOptions,i : INTEGER;
  290.     str : String; 
  291.   BEGIN
  292.     wp := NIL;
  293.     wp := NewWindow();
  294.     IF ( wp = NIL ) THEN RETURN NIL; END;
  295.     wp^ := DesktopWindow^;
  296.     wp^.Components := components;
  297.     wp^.State := WindowSSet{topped};
  298.     wp^.Title[0] := 0C;
  299.     wp^.Info[0]  := 0C;
  300.     wp^.RectList.Set := FALSE;
  301.     wp^.RectList.First := TRUE;
  302.     CalcWorkareaSize( wp );
  303.  
  304.     (* Now create the full size window *)
  305.     wp^.Handle :=  
  306.         Window.wind_create( wp^.Components,
  307.                             wp^.Outer.X,
  308.                             wp^.Outer.Y,
  309.                             wp^.Outer.Width,
  310.                             wp^.Outer.Height );
  311.  
  312.     IF ( NAME IN wp^.Components ) THEN 
  313.         SetAWindowTitle(wp, '*** No Title Set Yet ***');    
  314.     END;
  315.     IF ( INFO IN wp^.Components ) THEN 
  316.         SetAWindowInfo(wp, '*** No Information Set yet ***');    
  317.     END;
  318.     wp^.State := WindowSSet{};
  319.     RETURN wp;
  320.   END CreateAWindow;
  321.  
  322.  
  323. PROCEDURE SetAWindowTitle ( wp : WindowPtr; title : ARRAY OF CHAR );
  324.   CONST 
  325.         WindowName = 2;
  326.  
  327.   BEGIN
  328.      IF ( GetWindowIndex(wp) < 0     )      
  329.      OR NOT ( NAME IN wp^.Components ) THEN 
  330.         RETURN 
  331.      END; 
  332.      HideMouse;
  333.      Assign (title, wp^.Title); (* save the title somewhere permanent *)
  334.      IF Window.wind_set_long( wp^.Handle,
  335.                          WindowName,
  336.                          ADR(wp^.Title), LONGCARD(0))=0 THEN END;
  337.      ShowMouse;
  338.   END SetAWindowTitle;
  339.  
  340.  
  341. PROCEDURE SetAWindowInfo ( wp : WindowPtr; info : ARRAY OF CHAR );
  342.   CONST 
  343.         WindowInfo = 3;
  344.  
  345.   BEGIN
  346.      IF ( GetWindowIndex(wp) < 0     )      
  347.      OR NOT ( INFO IN wp^.Components ) THEN  
  348.         RETURN 
  349.      END; 
  350.      HideMouse;
  351.      Assign (info, wp^.Info); (* save the title somewhere permanent *)
  352.      IF Window.wind_set_long( wp^.Handle,
  353.                          WindowInfo,
  354.                          ADR(wp^.Info), LONGCARD(0))=0 THEN END;
  355.      ShowMouse;
  356.   END SetAWindowInfo;
  357.  
  358.  
  359.  
  360. PROCEDURE OpenAWindow( wp : WindowPtr ); (* Will use values in AWindow *)
  361.   VAR
  362.      i : INTEGER;
  363.      str     : String;
  364.  
  365.   BEGIN
  366.     IF  ( open IN wp^.State ) THEN
  367.        dumi := ShowAlert( "The Window is ALREADY OPEN!",1,1);
  368.        RETURN
  369.     ELSIF GetWindowIndex(wp) < 0 THEN
  370.        dumi := ShowAlert( "The Window does not exist!",1,1);
  371.        RETURN
  372.     END; (* if *)
  373.     FOR i := 0 TO CMaxWindows-1 DO
  374.       IF TheWindows[i] <> NIL THEN
  375.          EXCL( TheWindows[i]^.State, topped );
  376.       END;
  377.     END;
  378.     INCL( wp^.State, open);
  379.     INCL( wp^.State, topped);
  380.     HideMouse; (* Any time you write to screen you must hide the mouse *)
  381.     IF  ( wp^.Outer.X      <> DesktopWindow^.Outer.X ) 
  382.     OR  ( wp^.Outer.Y      <> DesktopWindow^.Outer.Y ) 
  383.     OR  ( wp^.Outer.Width  <> DesktopWindow^.Outer.Width ) 
  384.     OR  ( wp^.Outer.Height <> DesktopWindow^.Outer.Height ) THEN
  385.        CalcWorkareaSize(wp); (* re-calculate size for application *)
  386.     END; (* if *)
  387.  
  388.     IF ( NAME IN wp^.Components ) THEN 
  389.         SetAWindowTitle(wp, wp^.Title);    
  390.     END;
  391.     IF ( INFO IN wp^.Components ) THEN 
  392.         SetAWindowInfo(wp, wp^.Info);    
  393.     END;
  394.  
  395.     (* Draw the window *)
  396.     IF Window.wind_open(wp^.Handle,
  397.                         wp^.Outer.X,
  398.                         wp^.Outer.Y,
  399.                         wp^.Outer.Width,
  400.                         wp^.Outer.Height )=0 THEN END;
  401.     ClearAWindow(wp);
  402.     wp^.PrevSize := wp^.Workarea;
  403.  
  404.     (* Re-show mouse *)
  405.     ShowMouse;
  406.   END OpenAWindow;  
  407.  
  408.  
  409. PROCEDURE ClearAWindow( wp : WindowPtr ); (* There is only 1 window *)
  410.   VAR rectArray : CornersRect;
  411.   BEGIN  
  412.     IF  ( topped IN wp^.State ) THEN
  413.       HideMouse;
  414.       ToCornersRect( wp^.Workarea, rectArray);
  415.       VDI.vr_recfl( VDIHandle, rectArray.IntArray );
  416.       ShowMouse;
  417.    END; (* if *)                
  418.   END ClearAWindow;
  419.  
  420.  
  421. PROCEDURE CloseAWindow( wp : WindowPtr ); 
  422.   VAR  i : INTEGER;
  423.   BEGIN
  424.     IF ( GetWindowIndex(wp) < 0    ) THEN   
  425.        i := ShowAlert( "CloseWindow|The Window does not exist",1,1);
  426.  
  427.     ELSIF NOT ( open IN wp^.State ) THEN
  428.        RETURN;           
  429.  
  430.     ELSE           
  431.        i := Window.wind_close(wp^.Handle);
  432.        wp^.State := WindowSSet{};
  433.     END; (* if *)
  434.   END CloseAWindow;
  435.  
  436.  
  437. PROCEDURE DeleteAWindow( wp : WindowPtr ); (* Use handle in AWindow *)
  438.   VAR   i : INTEGER;
  439.       str : String;
  440.  
  441.   BEGIN
  442.     i := GetWindowIndex(wp);
  443.     IF i < 0 THEN RETURN; END;
  444.  
  445.     CloseAWindow(wp);
  446.     i := Window.wind_delete(wp^.Handle);
  447.     DestroyWindow(wp);
  448.     DEC(WindowCount);
  449.   END DeleteAWindow;
  450.  
  451.  
  452. PROCEDURE TerminateApplication;
  453.   VAR i : CARDINAL;
  454.   BEGIN
  455.     FOR i := 0 TO CMaxWindows-1 DO
  456.       IF TheWindows[i] <> NIL THEN
  457.          DeleteAWindow( TheWindows[i] );
  458.       END; (* if *)
  459.     END; 
  460.     DISPOSE( DesktopWindow );
  461.  
  462.     IF VDIHandle <> 0 THEN
  463.        VDI.v_clsvwk(VDIHandle);    
  464.        IF appl_exit() = 0 THEN END;
  465.     END; (* if *)
  466.   END TerminateApplication;
  467.  
  468.  
  469. PROCEDURE QueryIntersect(    Rect1, Rect2  : XYWHRect;
  470.                  VAR Intersect        : XYWHRect;) : BOOLEAN;
  471.  
  472.     PROCEDURE Min( n1, n2 : INTEGER ) : INTEGER;
  473.           BEGIN
  474.             IF n1 < n2 THEN RETURN n1; ELSE RETURN n2; END;
  475.           END Min;
  476.  
  477.     PROCEDURE Max( n1, n2 : INTEGER ) : INTEGER;
  478.           BEGIN
  479.             IF n1 > n2 THEN RETURN n1; ELSE RETURN n2; END;
  480.           END Max;
  481.  
  482.   BEGIN (* QueryIntersect *)
  483.     WITH Intersect DO
  484.     Width  := Min( (Rect1.X + Rect1.Width), (Rect2.X + Rect2.Width) ); 
  485.     Height := Min( (Rect1.Y + Rect1.Height),(Rect2.Y + Rect2.Height) ); 
  486.     X      := Max( Rect1.X, Rect2.X ); 
  487.     Y      := Max( Rect1.Y, Rect2.Y );
  488.         Width  := CARDINAL(INTEGER(Width) - INTEGER(X)); 
  489.         Height := CARDINAL(INTEGER(Height) - INTEGER(Y));
  490.         RETURN (     (INTEGER(Width)  > 0) 
  491.                  AND (INTEGER(Height) > 0) ); 
  492.     END; 
  493.   END QueryIntersect;
  494.  
  495.  
  496. (* routines for getting rectangle list     *)
  497. PROCEDURE SetUpdateRect( wp : WindowPtr; AreaRect : XYWHRect );
  498.  
  499.   BEGIN
  500.     WITH wp^.RectList DO
  501.       UpdateRect := AreaRect;
  502.       First      := TRUE;
  503.       Set        := TRUE;
  504.     END;
  505.   END SetUpdateRect;
  506.  
  507.  
  508. PROCEDURE ResetRectList( wp : WindowPtr );
  509.   BEGIN
  510.     wp^.RectList.First := TRUE;
  511.   END ResetRectList;
  512.  
  513.  
  514. PROCEDURE GetNextRect( wp : WindowPtr;
  515.                  VAR InterRect : XYWHRect; ) : BOOLEAN;
  516.   CONST FirstXYWH   = 11;
  517.         NextXYWH    = 12;
  518.  
  519.   VAR Intersect, More : BOOLEAN;
  520.  
  521.   BEGIN
  522.     WITH InterRect DO
  523.       LOOP
  524.         IF wp^.RectList.First THEN
  525.            dumc := Window.wind_get(wp^.Handle,
  526.                                    FirstXYWH, X, Y, Width, Height);
  527.            wp^.RectList.First := FALSE;
  528.         ELSE
  529.            dumc := Window.wind_get(wp^.Handle,
  530.                                    NextXYWH, X, Y, Width, Height);
  531.         END;       
  532.         IF ( Width <> 0 ) OR ( Height <> 0 ) THEN
  533.            Intersect := QueryIntersect( wp^.RectList.UpdateRect,
  534.                         InterRect,
  535.                                  InterRect );
  536.            IF Intersect THEN
  537.               RETURN TRUE
  538.            END;
  539.         ELSE
  540.            wp^.RectList.First := TRUE;
  541.            RETURN FALSE;
  542.         END;
  543.       END; (* loop *)
  544.     END; (* with *)
  545.   END GetNextRect;
  546.  
  547.  
  548. PROCEDURE Init;
  549.   VAR i : INTEGER;
  550.   BEGIN
  551.     FOR i := 0 TO HIGH(TheWindows) DO
  552.       TheWindows[i] := NIL;
  553.     END;
  554.     ScreenUpdateCount := 0;
  555.     WindowCount :=    0;
  556.     AESApplId     := -1;
  557.     VDIHandle     := 0;
  558.     ScreenResolution := getRez();
  559.     NEW( DesktopWindow );
  560.     IF DesktopWindow = NIL THEN
  561.        dumc := ShowAlert('Unable To Create Window',1,1);
  562.     ELSE
  563.        DesktopWindow^.Handle := 0;
  564.     END;
  565.   END Init;      
  566.  
  567.  
  568. BEGIN (* Start of initialisation code *)
  569.   Init;
  570. END ManyWindows.
  571.